﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using TcpLabCommon;
using Common.GeneralClass;
using System.Threading;

namespace Common
{
    public class TcpIpControl_Speed
    {
       public Socket clientSocket = null;
       public AccelerationDB accdb = new AccelerationDB ();
       List<byte> bs = new List<byte>();
       byte[] MsgBuffer = new byte[Marshal.SizeOf(new Acceleration_AllChannel())];
       public Thread ReceiveThread = null;
        public bool ConnectTcpIP()
        {
            bool yorn = true;
            try
            {

                IPAddress ip = IPAddress.Parse(Mdl_Class.ServerIP);
                clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                clientSocket.Connect(new IPEndPoint(ip, 3001)); //配置服务器IP与端口  
                //clientSocket.ReceiveBufferSize = MsgBuffer.Length;
                //clientSocket.BeginReceive(MsgBuffer, 0, MsgBuffer.Length, 0, new AsyncCallback(ReceiveCallback), null);
                //Console.WriteLine("Connected Server is OK");
                //ReceiveCallback();
                if (ReceiveThread != null && ReceiveThread.IsAlive)
                {
                    ReceiveThread.Abort();
                }
                ReceiveThread = new Thread(ReceiveCallback);
                ReceiveThread.Start();
            }
            catch (Exception ex)
            {
                yorn = false;
                Mdl_Class.WriteLog.sysErrLog("", "连接振动加速度下位机失败:" + ex.Message.ToString());
            }
            return yorn;
        }


        private void ReceiveCallback()
        {
            try
            {

                //无限长度的大容器
                int i;
                int successReceiveBytes = 1024;//缓冲区大小，你喜欢多大就多大，一般不超过2000，因为记得一次发送数据的大小好像 1千45左右，可以发送多次
                byte[] receivebytes = new byte[1024]; //这个1024 同上

                int[] channels_id = new int[] {11};//记录通道日志
                List<AccelerationDB> acqlistdata = null;
                while (true)
                {
                    if (clientSocket.Connected)
                    {
                        successReceiveBytes = clientSocket.Receive(receivebytes);//这个方法，你看看有没有重载，貌似有设置一次取多少的参数
                        for (i = 0; i < successReceiveBytes; i++)//临时取的，有多少都导入大容器
                        {
                            bs.Add(receivebytes[i]);
                            if (bs.Count == Marshal.SizeOf(new Acceleration_AllChannel()))
                            {
                             
                                Acceleration_AllChannel a = DeSerialize<Acceleration_AllChannel>(bs.ToArray());
                                acqlistdata = new List<AccelerationDB>();
                                //Console.WriteLine("--------接收数据时间：" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "--------");
                                for (int j = 0; j < a.channelstate.Length; j++)
                                {
                                    accdb = new AccelerationDB();

                                    if (a.channelstate[j] == 1)
                                    {
                                        accdb.acqId = Mdl_Class.acqId.ToString();
                                        accdb.acqName = Mdl_Class.acqName;
                                        accdb.channelId = j;
                                        accdb.dataPaket = a.Acceleration_all[j];
                                        //accdb.insertTime = DateTime.Now;
                                        accdb.projectId = Mdl_Class.projectId;
                                        accdb.taskId = Mdl_Class.taskId;
                                  
                                            if (Mdl_Class.speedAcqlist.ContainsKey(j))
                                            {
                                                Mdl_Class.speedAcqlist[j] = accdb;

                                            }
                                            else
                                            {
                                                Mdl_Class.speedAcqlist.Add(j, accdb);
                                            }
                                            acqlistdata.Add(accdb);
                            
                                   
                                    }
                                }

                                if (Mdl_Class.IsSaveData)//是否存储数据
                                {
                                    for (int m = 0; m < acqlistdata.Count; m++)
                                    {
                                        acqlistdata[m].insertTime = DateTime.Now;
                                        Mdl_Class.OperateAccelerationDB.AddAcceleration("T_B_ACQ_Acceleration", acqlistdata[m]);
                                        Thread.Sleep(1000);
                                        
                                    }
                                    acqlistdata.Clear();

                                 
                                }
                              
                                bs.Clear();
                            }
                        }
                    }
                    else
                    {
                        dispose();
                        break;
                    }
                }

            }
            catch (Exception ex)
            {
                Mdl_Class.WriteLog.sysErrLog("", "接收振动加速度下位机异常:"+ex.Message.ToString());
            }
        }

        public bool WriteChannelLog(int channels_id)
        {

            string logs_channel = "通道" + channels_id + "加速度FFT数据:";
            bool issave = false;
            string errMessage = "";
            //for (int j = 0; j < Mdl_Class.accdata.CHAccData[channels_id-1].FFTAmpDB.Length; j++)
            //{
            //    logs_channel = logs_channel + Mdl_Class.accdata.CHAccData[channels_id - 1].FFTAmpDB[j] + ",";
            //    try
            //    {
            //        double fftdat = Convert.ToDouble(Mdl_Class.accdata.CHAccData[channels_id - 1].FFTAmpDB[j]);
               
            //    }
            //    catch (Exception)
            //    {
            //        errMessage = "数据存在无法转化成double的数据，第" + (j + 1).ToString() + "位置";
            //        issave = true;
            //    }

            //}

       


            if (issave)
            {
                Mdl_Class.WriteLog.sysErrLog(errMessage, logs_channel);
            }
            return issave;
        }

        public void dispose()
        {
            try
            {
                if (ReceiveThread != null && ReceiveThread.IsAlive)
                {
                    ReceiveThread.Abort();
                }
                Thread.Sleep(500);
                this.clientSocket.Shutdown(SocketShutdown.Both);
                this.clientSocket.Close();
            }
            catch (Exception ex)
            {
            }
        }

        public byte[] Serialize<T>(T Data)
        {

            //得到结构体的大小
            int size = Marshal.SizeOf(Data);
            //创建byte数组
            byte[] bytes = new byte[size];
            //分配结构体大小的内存空间
            IntPtr structPtr = Marshal.AllocHGlobal(size);
            //将结构体拷到分配好的内存空间
            Marshal.StructureToPtr(Data, structPtr, false);
            //从内存空间拷到byte数组
            Marshal.Copy(structPtr, bytes, 0, size);
            //释放内存空间
            Marshal.FreeHGlobal(structPtr);
            //返回byte数组
            return bytes;
        }

        public T DeSerialize<T>(byte[] Data)
        {
            //得到结构体的大小
            int size = Marshal.SizeOf(typeof(T));
            //byte数组长度小于结构体的大小
            //if (size > Data.Length)
            //{
            //    //返回空
            //    return
            //}
            //分配结构体大小的内存空间
            IntPtr structPtr = Marshal.AllocHGlobal(size);
            //将byte数组拷到分配好的内存空间
            Marshal.Copy(Data, 0, structPtr, size);
            //将内存空间转换为目标结构体
            object obj = Marshal.PtrToStructure(structPtr, typeof(T));
            //释放内存空间
            Marshal.FreeHGlobal(structPtr);
            //返回结构体
            return (T)obj;
        }

    }
}
